package com.yunquan.ohana.db

import android.annotation.SuppressLint
import android.content.ContentValues
import android.database.Cursor
import com.yunquan.ohana.entity.LocalFrameEntity

class DBFrames {
    companion object {
        val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { DBFrames() }
    }

    private val readDB = DBManager.instance.readableDatabase
    private val writeDB = DBManager.instance.writableDatabase

    fun saveOrUpdate(data: LocalFrameEntity): Boolean {
        val cursor = readDB.query(DBManager.TABLE_FRAMES, null, "device_id = ?", arrayOf(data.deviceId), null, null, null)
        val result = if (cursor.moveToFirst()) {
            update(data)
        } else {
            insert(data)
        }
        cursor.close()
        return result
    }

    fun insert(data: LocalFrameEntity): Boolean {
        val result = writeDB.insert(DBManager.TABLE_FRAMES, null, toContentValues(data))
        return result != -1L
    }

    fun update(data: LocalFrameEntity): Boolean {
        if (data.deviceId == null) return false
        val result = writeDB.update(DBManager.TABLE_FRAMES, toContentValues(data), "device_id = ?", arrayOf(data.deviceId.toString()))
        return result != 0
    }

    fun delete(deviceId: String): Boolean {
        val result = writeDB.delete(DBManager.TABLE_FRAMES, "device_id = ?", arrayOf(deviceId))
        return result != 0
    }

    fun selectOne(deviceId: String): LocalFrameEntity? {
        val cursor = readDB.query(DBManager.TABLE_FRAMES, null, "device_id = ?", arrayOf(deviceId), null, null, null)
        var data: LocalFrameEntity? = null
        if (cursor.moveToFirst()) {
            data = toEntity(cursor)
        }
        cursor.close()
        return data
    }

    fun selectInDeviceIds(deviceIds: List<String>): List<LocalFrameEntity> {
        val cursor = readDB.query(DBManager.TABLE_FRAMES, null, "device_id IN (${deviceIds.joinToString(",")})", null, null, null, null)
        val data = mutableListOf<LocalFrameEntity>()
        while (cursor.moveToNext()) {
            data.add(toEntity(cursor))
        }
        cursor.close()
        return data
    }

    fun selectAll(): List<LocalFrameEntity> {
        val cursor = readDB.query(DBManager.TABLE_FRAMES, null, null, null, null, null, null)
        val data = mutableListOf<LocalFrameEntity>()
        while (cursor.moveToNext()) {
            data.add(toEntity(cursor))
        }
        cursor.close()
        return data
    }

    @SuppressLint("Range")
    fun toEntity(cursor: Cursor): LocalFrameEntity {
        val deviceId = cursor.getString(cursor.getColumnIndex("device_id"))
        val name = cursor.getString(cursor.getColumnIndex("name"))
        val location = cursor.getString(cursor.getColumnIndex("location"))
        val online = cursor.getInt(cursor.getColumnIndex("online"))
        return LocalFrameEntity(
            deviceId = deviceId,
            name = name,
            location = location,
            online = online,
        )
    }

    private fun toContentValues(data: LocalFrameEntity): ContentValues {
        val values = ContentValues()
        if (data.deviceId != null) {
            values.put("device_id", data.deviceId)
        }
        if (data.name != null) {
            values.put("name", data.name)
        }
        if (data.location != null) {
            values.put("location", data.location)
        }
        if (data.online != null) {
            values.put("online", data.online)
        }
        return values
    }
}